import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: DELL
 * Date: 2023-03-20
 * Time: 15:06
 */

// 约定的消息内容格式 (描述 body 请求内容)
class Message {
    // 设置成 public 无需提供 getter 和 setter 方法获取 body 消息内容
    public String from; // 谁
    public String to;   // 对谁
    public String message; // 说的消息

}

// 路径与约定相同(前后端约定请求路径)
@WebServlet("/message")
public class MessageServlet extends HttpServlet {

    // 创建一个列表存储每条消息
    // 基于 ObjectMapper.WriterValue 可以把 list<Message> 转为 json对象
    // private List<Message> messageList = new ArrayList<>();

    private ObjectMapper objectMapper = new ObjectMapper();

    // 向服务器提交数据 -- 浏览器把表白墙信息提交到服务器
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 创建一个 ObjectMapper 对象
        //ObjectMapper objectMapper = new ObjectMapper();
        // 把请求 body 中的内容读取出来, 解析成一个 Message 对象 ( body 数据是 json 格式)
        Message message = objectMapper.readValue(req.getInputStream(), Message.class);
        // 暂时先通过简单的方式保存
        //messageList.add(message);
        save(message);
        // 响应当中设置状态码(不设定默认也是200 表示当前数据提交成功)
        resp.setStatus(200);
    }

    // 向服务器获取数据 - 浏览器向服务器获取到之前的表白信息(一个 json 格式的数组. 每个下标对应一条表白数据 )
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //  将 List 中的数据取出来全部转为 json 格式数据
        //ObjectMapper objectMapper = new ObjectMapper();
        // 把 messageList 转为 json 字符串并且写到 resp.getWriter 响应 body 中

        // 设置响应格式(告诉浏览器数据是一个 json 格式, 并且按照 utf8 解析
        resp.setContentType("application/json; charset = utf8");
        // 把 messagelist 对象转为 json 格式字符串 并写入到响应中返回给浏览器
        List<Message> messageList = load();
        objectMapper.writeValue(resp.getWriter(), messageList);

    }

    // 删除最后一条消息(撤销当前消息)

    @Override
    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException {
        /*// 收到前端发来的 delete 请求, 将 list 中最后一个元素并删除
         resp.setContentType("application/json; charset = utf8");
         // 服务器内存中删除消息
        messageList.remove(messageList.size() - 1);*/

        List<Message> messageList = load();
        int count = messageList.size();
        Connection connection = null;
        PreparedStatement statement = null;

        // 1. 建立连接

            connection = DBUtil.getConnection();

        // 2. 构造 sql
        String sql = "delete from message where id = (select id from message limit ("+ count +"-1),1) ";

        try {
            statement = connection.prepareStatement(sql);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        // 3. 执行 sql
        try {
            statement.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        DBUtil.close(connection, statement, null);
    }

    // 往数据中存一条消息
    private void save(Message message) {
        Connection connection = null;
        PreparedStatement statement = null;
        // JDBC 操作
        try {
            // 建立连接
            connection = DBUtil.getConnection();
            // 构造 sql
            // 此处问号为一个占位符
            String sql = "insert into message value (?, ?, ?)";
            statement = connection.prepareStatement(sql);
            statement.setString(1, message.from);
            statement.setString(2, message.to);
            statement.setString(3, message.message);
            // 执行 sql 语句
            statement.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            // 关闭资源
            // resultSet 结果集合查询才用
            DBUtil.close(connection, statement, null);
        }
    }

    private List<Message> load() {
        // JDBC 查询操作
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;

        List<Message> messageList = new ArrayList<>();
        try{
            // 1. 建立连接
            connection = DBUtil.getConnection();
            // 2. 构造 sql
            String sql = "select * from message";
            statement = connection.prepareStatement(sql);
            // 3. 执行 sql
            resultSet = statement.executeQuery();
            // 4. 遍历结果结合
            while(resultSet.next()) {
                // 遍历该集合 获得的每一条消息是一个 Message 类
                Message message = new Message();
                message.from = resultSet.getString("from");
                message.to = resultSet.getString("to");
                message.message = resultSet.getString("message");
                messageList.add(message);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            // 5. 释放资源
            DBUtil.close(connection, statement, resultSet);
        }
        // 将构造后的 消息存在list中并返回
        return messageList;

    }
}
